/**
 * Copyright 2010 Butin Kirill <kiryaka@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.flexupload.status
{
	
	public class StatusBase
	{
		private static const CURRENT_SPEED_INTERVAL:int = 2000;
		private static const CURRENT_SPEED_SUBINTERVAL:int = 600;
		private static const MILLI_IN_SECOND:int = 1000;
		
		private var currentSpeedTimeStampArray:Array = new Array();
		private var currentSpeedBytesArray:Array = new Array();		
		
		protected var bytesTransfered:int = 0;
		
		protected var timeStart:uint;
		protected var currentTimeStamp:uint;
		
		protected var lastTimeStamp:uint = 0;
		private var spamInterval:int = 300;		
		
		public function StatusBase(){}
		public function startCounting():void{
			var date:Date = new Date();
			timeStart = date.getTime();
		}
		public function updateBytesTransfered(bytesTransfered:int):void{
			var date:Date = new Date();
			currentTimeStamp = date.getTime();
			this.bytesTransfered += bytesTransfered;
			processCurrentSpeedInfo(); 
		}
		private function processCurrentSpeedInfo():void{
			// todo may be some refactoring here??
			
			var length:int = currentSpeedTimeStampArray.length;
			
			// if array less than 2 elements - just push and quit
			if (length < 2){
				currentSpeedTimeStampArray.push(currentTimeStamp);
				currentSpeedBytesArray.push(bytesTransfered);
				return;
			}
			
			// if offset relative to previous (-2!!!) less than CURRENT_SPEED_SUBINTERVAL replace last element
			if ( (currentTimeStamp - currentSpeedTimeStampArray[length-2]) < CURRENT_SPEED_SUBINTERVAL){
				currentSpeedTimeStampArray[length-1] = currentTimeStamp;
				currentSpeedBytesArray[length-1] = bytesTransfered;
			}else{
				currentSpeedTimeStampArray.push(currentTimeStamp);
				currentSpeedBytesArray.push(bytesTransfered);
			}
			
			// if offset relative to first element more than CURRENT_SPEED_INTERVAL - shift first element
			if ( (currentTimeStamp - currentSpeedTimeStampArray[0]) > CURRENT_SPEED_INTERVAL){
				currentSpeedTimeStampArray.shift();
				currentSpeedBytesArray.shift();
			}
		}
		public function getBytesTransfered():int{
			return this.bytesTransfered;
		}
		public function getCurrentSpeed():int{
			var length:int = currentSpeedTimeStampArray.length;
			return (currentSpeedBytesArray[length-1] - currentSpeedBytesArray[0])*MILLI_IN_SECOND / 
				(currentSpeedTimeStampArray[length-1] - currentSpeedTimeStampArray[0]);
		}
		public function getAverageSpeed():int{
			return bytesTransfered*MILLI_IN_SECOND/(getCurrentTimeStamp() - timeStart);
		}
		protected function getCurrentTimeStamp():uint{
			return currentTimeStamp;
		}
		protected function isSpamSafety(stamp:uint):Boolean{
			if (stamp - lastTimeStamp > spamInterval) return false;
			lastTimeStamp = stamp;
			return true;
		}		
	}
}